package com.wumz.spring.write.v2.framework.beans.config;

import com.wumz.spring.write.v2.framework.beans.support.MyBeanDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * 读取配置文件中的内容，保存至 Properties
 * Created by wumz on 2020/9/28 10:50
 */
public class MyBeanDefinitionReader {

    private Properties contextConfig = new Properties();

    //缓存所有扫描发现的类，全类名
    private List<String> registryBeanClasses = new ArrayList<String>();

    //写一个构造方法，
    public MyBeanDefinitionReader(String ... configLocations) {
        try {
            //1、读取配置文件中的内容
            doLoadConfig(configLocations[0]);

            //2、扫描所有的包下面的类，缓存起来
            doScanner(contextConfig.getProperty("scanPackage"));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 扫描所有的包下面的类，缓存起来
     * @param scanPackage
     */
    private void doScanner(String scanPackage) {
        URL url = this.getClass().getClassLoader().getResource("/" + scanPackage.replaceAll("\\.", "/"));

        File classPath = new File(url.getFile());

        for (File file : classPath.listFiles()) {

            if (file.isDirectory()){
                this.doScanner(scanPackage + "." + file.getName());
            }else {
                if (!file.getName().endsWith(".class")){
                    continue;
                }
                //registryBeanClasses 缓存中保存的是全类名 = 包名+类名
                String beanClass = scanPackage + "." + file.getName().replace(".class", "");
                registryBeanClasses.add(beanClass);
            }
        }
    }

    /**
     * 读取配置文件中的内容
     * @param configLocation
     */
    private void doLoadConfig(String configLocation) {
        InputStream is = null;
        try {
            is = this.getClass().getClassLoader().getResourceAsStream(configLocation.replaceAll("classpath:", ""));
            this.contextConfig.load(is);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (null != is){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 解析配置文件，封装成BeanDefinition
     * @return
     */
    public List<MyBeanDefinition> loadBeanDefinitions() {
        List<MyBeanDefinition> result = new ArrayList<MyBeanDefinition>();
        try {
            for (String className : registryBeanClasses) {
                Class<?> beanClass = Class.forName(className);
                if(beanClass.isInterface()){continue;}
                //保存类对应的ClassName（全类名）
                //还有beanName
                //1、默认是类名首字母小写
                result.add(doCreateBeanDefinition(toLowerFirstCase(beanClass.getSimpleName()), beanClass.getName()));
                //2、自定义
                //3、接口注入
                for (Class<?> i : beanClass.getInterfaces()) {
                    result.add(doCreateBeanDefinition(i.getName(),beanClass.getName()));
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 创建BeanDefinition
     * @param beanName
     * @param beanClassName
     * @return
     */
    private MyBeanDefinition doCreateBeanDefinition(String beanName, String beanClassName) {
        MyBeanDefinition myBeanDefinition = new MyBeanDefinition();
        myBeanDefinition.setBeanClassName(beanClassName);
        myBeanDefinition.setFactoryBeanName(beanName);
        return myBeanDefinition;
    }


    /**
     * 首字母转小写
     * @param replace
     * @return
     */
    private String toLowerFirstCase(String replace) {
        char[] chars = replace.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);
    }

    public Properties getConfig() {
        return this.contextConfig;
    }
}
